﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace quizzer_linq_3
{
    /**Class: Quizzer
     * @author Spencer Estes
     * @version 1.1
     * Course : ITEC 4860 Spring 2012
     * Written: March 22, 2012
     * 
     * This class creates the game board and populates buttons with question data
     * 
     * Purpose: The purpose of this class is to provide a user interface that users can interact with and 
     * play a fun quizzing game
    */
    public partial class Quizzer : Form
    {
        //This is used to access the database
        private Quizzer_Data_Access dataAccess = new Quizzer_Data_Access();

        //An arraylist of questionIDs to populate the form
        private ArrayList questionIDList = new ArrayList();

        //An array of all questions after they have been parsed
        private ArrayList questionArray = new ArrayList();

        //Total number of questions
        private int numberOfQuestions;

        //Constants
        private const int HEIGHT_FOR_BOTTOM_BUTTONS = 100;
        private const int MAX_NUM_QUESTIONS = 50;
        
        //Used in giving user feedback on number of questions answered
        public int questionAnswered = 0;

        //List of unique topics the user has gotten incorrect
        public List<String> topicsIncorrect = new List<String>();

        //A public BoardButton that is accessed from QuizzerPopup to turn the button visible or invisible
        public BoardButton publicButton;

        //Integers used when laying out the gameboard
        public int xDistance = 0;
        public int yDistance;

        //Public score accessed from QuizzerPopup when incrementing score on correct or incorrect answer
        public int publicScore;

        /**Constructor: Quizzer(string)
         * This is the constructor to use when being sent in a specific gameset name
         * @param setName The name of the set to be imported
         * */
        public Quizzer(string setName)
        {
            InitializeComponent();
            Console.WriteLine("SetID is: " + setName);
            LoadGameSet(setName);
            scoreLabel.Text = "Score: 0";
        }

        /**Constructor: Quizzer(string[])
         * This is the constructor to use when being sent in a list of questions instead of a game set.
         * @param questionIDs the id numbers of the questions to be used for the game board.
         * */

        public Quizzer(string[] questionIDs)
        {
            InitializeComponent();
            CreateGameBoard(questionIDs);
        }

        /**Class: BoardButton extends Button
         * This class is necessary to create a button that can access questions from the database
         *
         * */
        public class BoardButton : Button
        {
            //The question the BoardButton will hold and pull from when creating QuestionPopup
            public BoardQuestion heldQuestion;
        }

        private void Quizzer_Load(object sender, EventArgs e)
        {
            
        }

        /**Method: LoadGameSet
         * This method loads the gameset from the database and sends the loaded set to parse
         * @param setName the name of the set to be loaded from the database
         * 
         * */
        private void LoadGameSet(string setName)
        {
            string loadedGameSet = dataAccess.GetGameSet(setName);
            ParseGameSet(loadedGameSet);
        }

        /**Method: ParseGameSet
         * This method receives a gameset from the database and creates arrays with the information
         * from the question.
         * 
         * @param gameSet The list of questionIDs delimited by '|'
         * */
        private void ParseGameSet(string gameSet)
        {
            string[] gameSetInfo = gameSet.Split('|');
            int gameSetID = Convert.ToInt32(gameSetInfo[0]);
            string[] questionIDs = dataAccess.questionsFromGameset(gameSetID).Split('\n');
            CreateGameBoard(questionIDs);
        }

        /**Method: CreatGameBoard
         * Lays out the game board and sets up all the BoardQuestions
         * 
         * @param gameSet The list of questionIDs delimited by '|'
         * */
        private void CreateGameBoard(string[] questionIDs)
        {
            int maxFormHeight = this.Size.Height - HEIGHT_FOR_BOTTOM_BUTTONS;
            int maxButtonHeight = maxFormHeight / (((questionIDs.Length - (questionIDs.Length % 5)) / 5) + 1);
            yDistance = -maxButtonHeight;
            numberOfQuestions = questionIDs.Count() - 1;
            for (int IDListCounter = 0; IDListCounter < Math.Min(questionIDs.Count()-1, MAX_NUM_QUESTIONS); IDListCounter++)
            {
                if(questionIDs[IDListCounter] != "")
                {
                    if (IDListCounter % 5 == 0)
                    {
                        xDistance = 0;
                        yDistance += maxButtonHeight;
                    }
                    else
                    {
                        xDistance += 160;
                    }

                    questionIDs[IDListCounter].Trim();
                    BoardQuestion newQuestion = new BoardQuestion(questionIDs[IDListCounter]);
                    BoardButton newQuestionButton = new BoardButton();

                    newQuestionButton.heldQuestion = newQuestion;
                    this.Controls.Add(newQuestionButton);
                    newQuestionButton.Bounds = new Rectangle(xDistance, yDistance, 160, maxButtonHeight);
                    newQuestionButton.Text = newQuestion.topic;
                    newQuestionButton.Click += new EventHandler(newQuestionButton_Click);
                }
            }
        }

        /** Method: newQuestionButton_Click
         * @author Spencer Estes
         * The event handler for clicking a question button
         * 
         * @param sender sender of the action
         * @param e event is triggered
        */
        void newQuestionButton_Click(object sender, EventArgs e)
        {
            openQuestionPopup((BoardButton)sender);
        }

        /**Method: openQuestionPopup
         * Displays a new QuestionPopup for the clicked BoardQuestion Button
         * 
         * @param clickedButton The button the user has clicked
         * */
        public void openQuestionPopup(BoardButton clickedButton)
        {
           QuestionPopup popupWindow = new QuestionPopup(clickedButton.heldQuestion, this);
           publicButton = clickedButton;
            
           popupWindow.ShowDialog();
        }

        /** Method: exitButton_Click
         * @author Spencer Estes
         * The event handler for exiting the gameboard
         * 
         * @param sender sender of the action
         * @param e event is triggered
        */
        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /**Method: UpdateScore
         * Updates the score so the user sees the correct value in the scoreLabel
         * 
         * */
        public void UpdateScore()
        {
            scoreLabel.Text = "Score: " + publicScore;
        }

        /**Method: checkNumberQuestionsAnswered
         * Collects data for user feedback and shows them message boxes with said data
         * 
         * */
        public void checkNumberQuestionsAnswered()
        {
            if (questionAnswered == Math.Min(numberOfQuestions, MAX_NUM_QUESTIONS) && questionAnswered != 0)
            {
                String topics = "";
                for (int topicCounter = 0; topicCounter < topicsIncorrect.Count; topicCounter++)
                {
                    topics = topics + topicsIncorrect[topicCounter] + "\n";
                }

                if (topics == "")
                {
                    MessageBox.Show("Nice Job!\nYou got them all correct!", "Awesome!");
                }
                else
                {
                    MessageBox.Show("Nice Try!\nYou need to work on these topics:\n\n" + topics, "Results");
                }
            }
        }

        /**Method: addToTopicsIncorrects
         * Adds a topic to the List of incorrect topics
         * 
         * @param topic The topic to add to the Incorrect list
         * */
        public void addToTopicsIncorrect(string topic)
        {
            Boolean duplicate = false;
            for (int topicCounter = 0; topicCounter < topicsIncorrect.Count; topicCounter++)
            {
                if (topicsIncorrect[topicCounter].Equals(topic))
                {
                    duplicate = true;
                }
            }
            if (!duplicate)
            {
                topicsIncorrect.Add(topic);
            }
        }
    }
}
